#include "PrecompiledHeaders.h"
#include "ReplayState.h"
#include "PlayState.h"

std::vector<ReplayController *> ReplayState::replay_controllers(0);

/*
 * Deal with a key press action
 */
bool ReplayState::keyPressed(const OIS::KeyEvent & e)
{
    switch (e.key)
    {
        case OIS::KC_ESCAPE:
            stop_playing = true;
            break;
            
        case OIS::KC_UP:
            if(play_speed < 3) play_speed *= 1.2;
            break;
            
        case OIS::KC_DOWN:
            if(play_speed > 0.3) play_speed /= 1.2;
            break;
            
        default:
            break;
    }
    return true;
}

/*
 * Set up all players in the game to be controlled by their replays
 */
void ReplayState::initialisePlayers()
{
    // Change input device to replay and assign a temporary session
    std::vector<ReplayController *>::iterator r_it;
    std::vector<Player *>::iterator p_it;
    for(r_it = replay_controllers.begin(), p_it = players.begin(); r_it != replay_controllers.end() && p_it != players.end(); r_it++, p_it++)
    {
        (*r_it)->setPlayState(this);
        (*p_it)->changeInputDevice(*r_it);
        (*p_it)->setPlayState(this);
        (*p_it)->getSession()->setReplay(true);
        (*p_it)->show();
    }
    
    // don't use the pod
    main_player->usePod(false);
}

/*
 * Nothing extra needs to be done when we start playing this state
 */
void ReplayState::startPlaying()
{
    if (!out_file) out_file = fopen("REPLAY.txt", "w");
    play_speed = 1;
    in_replay = true;
    ogrenewt_controller_index = 0;
}

/*
 * When we've finished playing this state, remove all replay controllers
 */
void ReplayState::stopPlaying()
{
    // remove all temporary sessions
    PlayerVector::iterator it;
    for(it = PlayState::players.begin(); it != PlayState::players.end(); it++)
    {
        Player *p = *it;
        p->getSession()->setReplay(false);
        p->changeInputDevice(NULL);
    }
    
    // reset camera, hide overlay and pop
    camera->reset();
    replay_overlay->hide();
    popGameState();
}

void ReplayState::initialiseExtraOverlays()
{
    Ogre::OverlayManager * overlay_manager = Ogre::OverlayManager::getSingletonPtr();
    replay_overlay = overlay_manager->getByName("ReplayOverlay");
    Ogre::OverlayElement *text = overlay_manager->getOverlayElement("Replay/Text");
    text->setCaption("REPLAY");
}

void ReplayState::updateExtraOverlays()
{
    if(time_until_user_can_control > 0 && overlays_enabled) replay_overlay->show();
    else if(timer_goal - (int)timer_goal > 0.5 && overlays_enabled) replay_overlay->show();
    else replay_overlay->hide();
}

void ReplayState::addReplay(ReplayController *rc)
{
    replay_controllers.push_back(rc);
}

void ReplayState::removeAllReplays()
{
    //replay_controllers are deleted when players are deleted
    replay_controllers.clear();
}
bool ReplayState::ogreNewtNeedsUpdate()
{
    if(ogrenewt_controller_index < players.size())
        if(players[ogrenewt_controller_index])
            if(players[ogrenewt_controller_index]->isFinished())
                ogrenewt_controller_index++;
    if(ogrenewt_controller_index >= replay_controllers.size())
    {
        stop_playing = true;
        return false;
    }
    return replay_controllers[ogrenewt_controller_index]->ogreNewtNeedsUpdate(ogre_newt_time);
}

float ReplayState::getOgreNewtUpdateTime()
{
    float ret = replay_controllers[ogrenewt_controller_index]->getOgreNewtUpdateTime();
    //if(ogre_time < 0.1)
    //fprintf(PlayState::out_file, "OgreNewt updated with %f seconds\n", ret); // replay debuffing info
    return ret;
}

void ReplayState::setStopPlaying()
{
    if(stop_playing) return;
    stop_playing = true;
    std::vector<Player *>::iterator it;
    for(it = players.begin(); it != players.end(); it++)
        stop_playing = stop_playing && (!((*it)->isVisible()) || (*it)->isFinished());
}

void ReplayState::playerFallout()
{
    stop_playing = true;
}
